package com.cmii.sjw.department.control.jsc.service.impl;

import cn.dev33.satoken.dao.SaTokenDao;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.Header;
import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.cmii.sjw.department.control.jsc.config.OneFormConfig;
import com.cmii.sjw.department.control.jsc.mapper.*;
import com.cmii.sjw.department.control.jsc.model.*;
import com.cmii.sjw.department.control.jsc.service.BenefitService;
import com.cmii.sjw.department.control.jsc.service.OneFormService;
import com.cmii.sjw.department.control.jsc.util.ApiDbHelper;
import com.cmii.sjw.department.control.jsc.util.CampusDetailParser;
import com.cmii.sjw.department.control.jsc.util.Result;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.client.utils.URIBuilder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.atomic.AtomicInteger;


/**
 * @Author lz
 * @Date 2025-05-21 周三 14:43
 * @Version 1.0
 */
@Slf4j
@Service
public class BenefitServiceImpl implements BenefitService {

    @Autowired
    private OneFormConfig ybtConfig;
    @Autowired
    private OneFormService oneFormService;
    @Autowired
    private MentaheathMapper mentaheathMapper;
    @Autowired
    private HeathDetailMapper heathDetailMapper;
    @Autowired
    private PhysicalHealthMapper physicalHealthMapper;
    @Autowired
    private PhysicalDetailMapper physicalDetailMapper;
    @Autowired
    private PeriodStudentMapper periodStudentMapper;
    @Autowired
    private StudentDetailMapper studentDetailMapper;
    @Autowired
    private TownMapper townMapper;
    @Autowired
    private PeriodGenderMapper periodGenderMapper;

    @Autowired
    private EnrolledMapper enrolledMapper;
    @Autowired
    private PhysicalMapper physicalMapper;
    @Autowired
    private VariousTypesMapper variousTypesMapper;
    @Autowired
    private AlterationMapper alterationMapper;
    @Autowired
    private CountyStudentMapper countyStudentMapper;
    @Autowired
    private LayoutMapper layoutMapper;
    @Autowired
    private AverageAreaMapper averageAreaMapper;
    @Autowired
    private CampusDetailMapper campusDetailMapper;
    @Autowired
    private SummaryMapper summaryMapper;


    @Autowired
    private SaTokenDao dao;
    private static final int TOKEN_EXPIRE_SECONDS = 7140;


    public String getToken() {
        String token = null;
        try {
            URIBuilder uriBuilder = new URIBuilder(ybtConfig.getUrl() + "/api/v1/auth/getToken");
            uriBuilder.addParameter("appId", ybtConfig.getAppId());
            uriBuilder.addParameter("secretKey", ybtConfig.getSecretKey());
            String url = uriBuilder.build().toString();

            String apiResult = HttpUtil.createPost(url)
                    .header(Header.CONTENT_TYPE, "application/json")
                    .execute()
                    .body();
            log.info("一表通Token ,url:{},apiResult:{}", url, apiResult);
            JSONObject content = JSON.parseObject(apiResult);

            if ("0".equals(content.getObject("code", String.class))) {
                log.info("一表通Token结果:{}", content.getString("data"));
                token = content.getJSONObject("data").get("access_token").toString();
            } else {
                log.error("一表通Token结果异常 responseCode:{}", content.getString("code"));
            }
        } catch (Exception e) {
            log.error("一表通Token请求异常 | 错误类型:{} | 详细信息:", e.getClass().getSimpleName(), e);
        }
        return token;
    }

    @Override
    public String TokenManager() {
        String token = dao.get("one-form:token");
        if (StringUtils.isEmpty(token)) {
            synchronized (this) {
                token = dao.get("one-form:token"); // 双重检查
                if (StringUtils.isEmpty(token)) {
                    try {
                        token = getToken();
                        log.info("获取新的一表通Token:{}", token);
                        dao.set("one-form:token", token, TOKEN_EXPIRE_SECONDS);
                    } catch (Exception e) {
                        log.error("生成Token失败", e);
                        throw new RuntimeException("Token生成异常"); // 根据业务需求处理异常
                    }
                }
            }
        }
        return token;
    }

    @Override
    public Result saveMentaHeath(String year) {
        if (StrUtil.isBlank(year)) {
            return Result.error("year 参数不能为空");
        }

        String token = TokenManager();
        if (StrUtil.isBlank(token)) {
            return Result.error("获取 token 失败");
        }

        String endpoint = "/api/v1/data/mentaHeath";
        String baseUrl = ybtConfig.getUrl();
        int total = 0;

        // 汇总数据
        total += fetchAndSaveMentalHealth(token, baseUrl, endpoint, year, null, null, "汇总");

        // 区县汇总数据
        total += fetchAndSaveMentalHealth(token, baseUrl, endpoint, year, "1", null, "区县汇总");

        // 高校汇总数据
        total += fetchAndSaveMentalHealth(token, baseUrl, endpoint, year, "2", null, "高校汇总");

        // 获取区县列表
        Result countyResult = oneFormService.countyList(year);
        if (countyResult == null || !Objects.equals(countyResult.getCode(), 200)) {
            return Result.error("获取区县列表失败：" + countyResult.getMessage());
        }

        JSONArray countyData = (JSONArray) countyResult.getData();
        if (countyData != null) {
            for (int i = 0; i < countyData.size(); i++) {
                JSONObject county = countyData.getJSONObject(i);
                String countyName = county.getString("countyName");
                if (StrUtil.isNotBlank(countyName)) {
                    total += fetchAndSaveMentalHealth(token, baseUrl, endpoint, year, "1", countyName, countyName);
                }
            }
        }
        // 获取高校列表
        Result highResult = oneFormService.highList(year);
        if (highResult == null || !Objects.equals(highResult.getCode(), 200)) {
            return Result.error("获取高校列表失败：" + (highResult == null ? "null" : highResult.getMessage()));
        }

        JSONArray highData = (JSONArray) highResult.getData();
        if (highData != null) {
            for (int i = 0; i < highData.size(); i++) {
                JSONObject high = highData.getJSONObject(i);
                String highName = high.getString("orgnazitionName");
                if (StrUtil.isNotBlank(highName)) {
                    total += fetchAndSaveMentalHealth(token, baseUrl, endpoint, year, "2", highName, highName);
                }
            }
        }

        log.info("心理健康数据保存完成，共 {} 条", total);
        return Result.success("心理健康数据保存完成，共 " + total + " 条记录");
    }

    private int fetchAndSaveMentalHealth(String token, String baseUrl, String endpoint,
                                         String year, String type, String nameParam, String name) {
        JSONObject form = new JSONObject();
        form.put("year", year);
        if (StrUtil.isNotBlank(type)) form.put("type", type);
        if (StrUtil.isNotBlank(nameParam)) form.put("name", nameParam);

        try {
            JSONObject result = ApiDbHelper.postAndParse(token, baseUrl, endpoint, form);
            JSONObject data = result.getJSONObject("data");
            if (data != null && !data.isEmpty()) {
                Mentaheath mentalHealth = new Mentaheath();
                mentalHealth.setName(name);

                mentalHealth.setHighPsychology(data.getInteger("highPsychology"));
                mentalHealth.setBasePsychology(data.getInteger("basePsychology"));
                mentalHealth.setPsychologyArea(data.getBigDecimal("psychologyArea"));

                ApiDbHelper.fillTimestamps(mentalHealth);
                ApiDbHelper.insertOrUpdate(mentaheathMapper, mentalHealth, (LambdaQueryWrapper<Mentaheath> wrapper) ->
                        wrapper.eq(Mentaheath::getName, mentalHealth.getName())
                );
                return 1;
            }
        } catch (Exception e) {
            log.error("调用心理健康接口失败：[name={}, type={}]：{}", name, type, e.getMessage());
        }
        return 0;
    }

    @Override
    public Result saveVisionHeathDetail(String year) {
        if (StrUtil.isBlank(year)) {
            return Result.error("year 参数不能为空");
        }

        String token = TokenManager();
        if (StrUtil.isBlank(token)) {
            return Result.error("获取 token 失败");
        }

        String endpoint = "/api/v1/data/visionHeathDetail";
        String baseUrl = ybtConfig.getUrl();

        JSONObject form = new JSONObject();
        form.put("year", year);

        try {
            JSONObject result = ApiDbHelper.postAndParse(token, baseUrl, endpoint, form);
            JSONArray dataArray = result.getJSONArray("data");

            if (CollUtil.isEmpty(dataArray)) {
                return Result.error("接口返回数据为空");
            }

            int total = 0;
            for (int i = 0; i < dataArray.size(); i++) {
                JSONObject item = dataArray.getJSONObject(i);
                HeathDetail detail = new HeathDetail();

                detail.setName(item.getString("name"));
                detail.setVision(item.getIntValue("vision"));
                detail.setVisionRate(item.getString("visionRate"));
                ApiDbHelper.fillTimestamps(detail);

                ApiDbHelper.insertOrUpdate(heathDetailMapper, detail, wrapper ->
                        wrapper.eq(HeathDetail::getName, detail.getName())
                );
                total++;
            }

            log.info("视力健康详情数据保存成功，共 {} 条", total);
            return Result.success("保存成功，共 " + total + " 条数据");
        } catch (Exception e) {
            log.error("调用视力健康接口失败：{}", e.getMessage(), e);
            return Result.error("调用接口失败：" + e.getMessage());
        }
    }

    @Override
    public Result savePhysicalHealth(String year) {
        if (StrUtil.isBlank(year)) {
            return Result.error("year 参数不能为空");
        }

        String token = TokenManager();
        if (StrUtil.isBlank(token)) {
            return Result.error("获取 token 失败");
        }

        String endpoint = "/api/v1/data/physicalHealth";
        String baseUrl = ybtConfig.getUrl();
        int total = 0;

        try {
            // === 1. 保存“汇总”数据 ===
            JSONObject totalForm = new JSONObject();
            totalForm.put("year", year);

            JSONObject totalResult = ApiDbHelper.postAndParse(token, baseUrl, endpoint, totalForm);
            JSONArray totalData = totalResult.getJSONArray("data");

            if (CollUtil.isNotEmpty(totalData)) {
                for (int i = 0; i < totalData.size(); i++) {
                    JSONObject item = totalData.getJSONObject(i);

                    PhysicalHealth entity = new PhysicalHealth();
                    entity.setName("汇总");
                    entity.setSchoolType(item.getString("name"));
                    entity.setARate(item.getString("A"));
                    entity.setBRate(item.getString("B"));
                    entity.setCRate(item.getString("C"));
                    entity.setDRate(item.getString("D"));
                    entity.setERate(item.getString("E"));

                    ApiDbHelper.fillTimestamps(entity);

                    ApiDbHelper.insertOrUpdate(physicalHealthMapper, entity, wrapper ->
                            wrapper.eq(PhysicalHealth::getName, entity.getName())
                                    .eq(PhysicalHealth::getSchoolType, entity.getSchoolType())
                    );

                    total++;
                }
            }

            // === 2. 获取区县列表 ===
            Result countyResult = oneFormService.countyList(year);
            if (countyResult == null || countyResult.getCode() != 200) {
                return Result.error("获取区县列表失败：" + (countyResult != null ? countyResult.getMessage() : "返回为空"));
            }

            JSONArray array = (JSONArray) countyResult.getData();
            List<String> countyList = new ArrayList<>();
            for (int i = 0; i < array.size(); i++) {
                JSONObject item = array.getJSONObject(i);
                String name = item.getString("countyName");
                if (StrUtil.isNotBlank(name)) {
                    countyList.add(name);
                }
            }

            // === 3. 循环请求每个区县的数据 ===
            for (String county : countyList) {
                JSONObject form = new JSONObject();
                form.put("year", year);
                form.put("name", county);

                JSONObject result = ApiDbHelper.postAndParse(token, baseUrl, endpoint, form);
                JSONArray dataArray = result.getJSONArray("data");

                if (CollUtil.isNotEmpty(dataArray)) {
                    for (int i = 0; i < dataArray.size(); i++) {
                        JSONObject item = dataArray.getJSONObject(i);

                        PhysicalHealth entity = new PhysicalHealth();
                        entity.setName(county);
                        entity.setSchoolType(item.getString("name"));
                        entity.setARate(item.getString("A"));
                        entity.setBRate(item.getString("B"));
                        entity.setCRate(item.getString("C"));
                        entity.setDRate(item.getString("D"));
                        entity.setERate(item.getString("E"));

                        ApiDbHelper.fillTimestamps(entity);

                        ApiDbHelper.insertOrUpdate(physicalHealthMapper, entity, wrapper ->
                                wrapper.eq(PhysicalHealth::getName, entity.getName())
                                        .eq(PhysicalHealth::getSchoolType, entity.getSchoolType())
                        );

                        total++;
                    }
                }
            }

            log.info("体质健康数据保存完成，共 {} 条", total);
            return Result.success("体质健康数据保存完成，共 " + total + " 条记录");

        } catch (Exception e) {
            log.error("保存体质健康数据失败：{}", e.getMessage(), e);
            return Result.error("保存失败：" + e.getMessage());
        }
    }

    @Override
    public Result savePhysicalHealthDetail(String year) {
        if (StrUtil.isBlank(year)) {
            return Result.error("year 参数不能为空");
        }

        String token = TokenManager();
        if (StrUtil.isBlank(token)) {
            return Result.error("获取 token 失败");
        }

        String endpoint = "/api/v1/data/physicalHealthDetail";
        String baseUrl = ybtConfig.getUrl();

        JSONObject form = new JSONObject();
        form.put("year", year);

        try {
            JSONObject result = ApiDbHelper.postAndParse(token, baseUrl, endpoint, form);
            JSONArray dataArray = result.getJSONArray("data");

            if (CollUtil.isEmpty(dataArray)) {
                return Result.error("接口返回数据为空");
            }

            int total = 0;
            for (int i = 0; i < dataArray.size(); i++) {
                JSONObject item = dataArray.getJSONObject(i);
                PhysicalDetail entity = new PhysicalDetail();

                entity.setName(item.getString("name"));
                entity.setYear(year);
                entity.setARate(item.getString("a"));
                entity.setBRate(item.getString("b"));
                entity.setCRate(item.getString("c"));
                entity.setDRate(item.getString("d"));
                entity.setERate(item.getString("e"));

                ApiDbHelper.fillTimestamps(entity);

                ApiDbHelper.insertOrUpdate(physicalDetailMapper, entity, wrapper ->
                        wrapper.eq(PhysicalDetail::getName, entity.getName())
                                .eq(PhysicalDetail::getYear, entity.getYear())
                );

                total++;
            }

            log.info("体质健康详情数据保存成功，共 {} 条", total);
            return Result.success("体质健康详情数据保存成功，共 " + total + " 条记录");

        } catch (Exception e) {
            log.error("调用体质健康详情接口失败：{}", e.getMessage(), e);
            return Result.error("保存失败：" + e.getMessage());
        }
    }

    @Override
    public Result savePeriodStudent(String year) {
        if (StrUtil.isBlank(year)) {
            return Result.error("year 参数不能为空");
        }

        String token = TokenManager();
        if (StrUtil.isBlank(token)) {
            return Result.error("获取 token 失败");
        }

        String endpoint = "/api/v1/data/periodStudent";
        String baseUrl = ybtConfig.getUrl();

        JSONObject form = new JSONObject();
        form.put("year", year);

        try {
            JSONObject result = ApiDbHelper.postAndParse(token, baseUrl, endpoint, form);
            JSONArray dataArray = result.getJSONArray("data");

            if (CollUtil.isEmpty(dataArray)) {
                return Result.error("接口返回数据为空");
            }

            int total = 0;
            for (int i = 0; i < dataArray.size(); i++) {
                JSONObject item = dataArray.getJSONObject(i);
                PeriodStudent entity = new PeriodStudent();

                entity.setName(item.getString("name"));
                entity.setNum(item.getIntValue("num"));
                entity.setPercentage(item.getString("percentage"));

                ApiDbHelper.fillTimestamps(entity);

                ApiDbHelper.insertOrUpdate(periodStudentMapper, entity, wrapper ->
                        wrapper.eq(PeriodStudent::getName, entity.getName())
                );

                total++;
            }

            log.info("在校学生结构数据保存成功，共 {} 条", total);
            return Result.success("在校学生结构数据保存成功，共 " + total + " 条记录");

        } catch (Exception e) {
            log.error("调用在校学生结构接口失败：{}", e.getMessage(), e);
            return Result.error("保存失败：" + e.getMessage());
        }
    }

    @Override
    public Result saveStudentDetail(String year) {
        if (StrUtil.isBlank(year)) {
            return Result.error("year 参数不能为空");
        }

        String token = TokenManager();
        if (StrUtil.isBlank(token)) {
            return Result.error("获取 token 失败");
        }

        String endpoint = "/api/v1/data/studentDetail";
        String baseUrl = ybtConfig.getUrl();

        JSONObject form = new JSONObject();
        form.put("year", year);

        try {
            JSONObject result = ApiDbHelper.postAndParse(token, baseUrl, endpoint, form);
            JSONArray dataArray = result.getJSONArray("data");

            if (CollUtil.isEmpty(dataArray)) {
                return Result.error("接口返回数据为空");
            }

            int total = 0;
            for (int i = 0; i < dataArray.size(); i++) {
                JSONObject item = dataArray.getJSONObject(i);
                StudentDetail entity = new StudentDetail();

                entity.setName(item.getString("name"));
                entity.setKindergarten(item.getIntValue("kindergarten"));
                entity.setSmallSchool(item.getIntValue("primary"));
                entity.setJunior(item.getIntValue("junior"));
                entity.setSenior(item.getIntValue("senior"));
                entity.setVocational(item.getIntValue("vocational"));
                entity.setSpecial(item.getIntValue("special"));
                entity.setSpecialized(item.getIntValue("specialized"));
                entity.setHigh(item.getIntValue("high"));
                entity.setStudent(item.getIntValue("student"));

                ApiDbHelper.fillTimestamps(entity);

                ApiDbHelper.insertOrUpdate(studentDetailMapper, entity, wrapper ->
                        wrapper.eq(StudentDetail::getName, entity.getName())
                );

                total++;
            }

            log.info("在校学生明细数据保存成功，共 {} 条", total);
            return Result.success("在校学生明细数据保存成功，共 " + total + " 条记录");

        } catch (Exception e) {
            log.error("调用在校学生明细接口失败：{}", e.getMessage(), e);
            return Result.error("保存失败：" + e.getMessage());
        }
    }

    @Override
    public Result saveTown(String year) {
        if (StrUtil.isBlank(year)) {
            return Result.error("year 参数不能为空");
        }

        String token = TokenManager();
        if (StrUtil.isBlank(token)) {
            return Result.error("获取 token 失败");
        }

        String endpoint = "/api/v1/data/town";
        String baseUrl = ybtConfig.getUrl();

        int total = 0;

        try {
            // 1. 保存全市汇总数据
            JSONObject summaryForm = new JSONObject();
            summaryForm.put("year", year);

            JSONObject summaryResult = ApiDbHelper.postAndParse(token, baseUrl, endpoint, summaryForm);
            JSONArray summaryArray = summaryResult.getJSONArray("data");

            if (CollUtil.isNotEmpty(summaryArray)) {
                for (int i = 0; i < summaryArray.size(); i++) {
                    JSONObject item = summaryArray.getJSONObject(i);
                    Town entity = new Town();
                    entity.setName(item.getString("name"));
                    entity.setCounty("全市汇总");
                    entity.setTown(item.getString("town"));
                    entity.setCity(item.getString("city"));
                    entity.setVillage(item.getString("village"));

                    ApiDbHelper.fillTimestamps(entity);
                    ApiDbHelper.insertOrUpdate(townMapper, entity, wrapper ->
                            wrapper.eq(Town::getName, entity.getName())
                                    .eq(Town::getCounty, entity.getCounty())
                    );
                    total++;
                }
            }

            // 2. 获取区县列表
            Result countyResult = oneFormService.countyList(year);
            if (countyResult != null && countyResult.getCode() == 0) {
                return Result.error("获取区县列表失败");
            }

            JSONArray countyArray = (JSONArray) countyResult.getData();
            for (int i = 0; i < countyArray.size(); i++) {
                JSONObject county = countyArray.getJSONObject(i);
                String countyName = county.getString("countyName");
                if (StrUtil.isBlank(countyName)) {
                    continue;
                }

                JSONObject form = new JSONObject();
                form.put("year", year);
                form.put("name", countyName);

                JSONObject result = ApiDbHelper.postAndParse(token, baseUrl, endpoint, form);
                JSONArray dataArray = result.getJSONArray("data");

                if (CollUtil.isEmpty(dataArray)) {
                    continue;
                }

                for (int j = 0; j < dataArray.size(); j++) {
                    JSONObject item = dataArray.getJSONObject(j);
                    Town entity = new Town();
                    entity.setName(item.getString("name"));
                    entity.setCounty(countyName);
                    entity.setTown(item.getString("town"));
                    entity.setCity(item.getString("city"));
                    entity.setVillage(item.getString("village"));

                    ApiDbHelper.fillTimestamps(entity);
                    ApiDbHelper.insertOrUpdate(townMapper, entity, wrapper ->
                            wrapper.eq(Town::getName, entity.getName())
                                    .eq(Town::getCounty, entity.getCounty())
                    );
                    total++;
                }
            }

            log.info("城乡结构数据保存完成，共 {} 条", total);
            return Result.success("城乡结构数据保存完成，共 " + total + " 条记录");

        } catch (Exception e) {
            log.error("城乡结构数据保存失败：{}", e.getMessage(), e);
            return Result.error("保存失败：" + e.getMessage());
        }
    }

    @Override
    public Result savePeriodGender(String year) {
        if (StrUtil.isBlank(year)) {
            return Result.error("year 参数不能为空");
        }

        String token = TokenManager();
        if (StrUtil.isBlank(token)) {
            return Result.error("获取 token 失败");
        }

        String endpoint = "/api/v1/data/periodGender";
        String baseUrl = ybtConfig.getUrl();

        int total = 0;

        try {
            // 1. 全市汇总数据
            JSONObject summaryForm = new JSONObject();
            summaryForm.put("year", year);

            JSONObject summaryResult = ApiDbHelper.postAndParse(token, baseUrl, endpoint, summaryForm);
            JSONArray summaryArray = summaryResult.getJSONArray("data");

            if (CollUtil.isNotEmpty(summaryArray)) {
                for (int i = 0; i < summaryArray.size(); i++) {
                    JSONObject item = summaryArray.getJSONObject(i);
                    PeriodGender entity = new PeriodGender();
                    entity.setCounty("全市汇总");
                    entity.setName(item.getString("name"));
                    entity.setBoy(item.getString("boy"));
                    entity.setGirl(item.getString("girl"));

                    ApiDbHelper.fillTimestamps(entity);
                    ApiDbHelper.insertOrUpdate(periodGenderMapper, entity, wrapper ->
                            wrapper.eq(PeriodGender::getName, entity.getName())
                                    .eq(PeriodGender::getCounty, entity.getCounty())
                    );
                    total++;
                }
            }

            // 2. 区县数据
            Result countyResult = oneFormService.countyList(year);
            if (countyResult != null && countyResult.getCode() == 0) {
                return Result.error("获取区县列表失败");
            }

            JSONArray countyArray = (JSONArray) countyResult.getData();
            for (int i = 0; i < countyArray.size(); i++) {
                JSONObject county = countyArray.getJSONObject(i);
                String countyName = county.getString("countyName");
                if (StrUtil.isBlank(countyName)) continue;

                JSONObject form = new JSONObject();
                form.put("year", year);
                form.put("name", countyName);

                JSONObject result = ApiDbHelper.postAndParse(token, baseUrl, endpoint, form);
                JSONArray dataArray = result.getJSONArray("data");

                if (CollUtil.isEmpty(dataArray)) continue;

                for (int j = 0; j < dataArray.size(); j++) {
                    JSONObject item = dataArray.getJSONObject(j);
                    PeriodGender entity = new PeriodGender();
                    entity.setCounty(countyName);
                    entity.setName(item.getString("name"));
                    entity.setBoy(item.getString("boy"));
                    entity.setGirl(item.getString("girl"));

                    ApiDbHelper.fillTimestamps(entity);
                    ApiDbHelper.insertOrUpdate(periodGenderMapper, entity, wrapper ->
                            wrapper.eq(PeriodGender::getName, entity.getName())
                                    .eq(PeriodGender::getCounty, entity.getCounty())
                    );
                    total++;
                }
            }

            log.info("性别结构数据保存完成，共 {} 条", total);
            return Result.success("性别结构数据保存完成，共 " + total + " 条记录");

        } catch (Exception e) {
            log.error("性别结构数据保存失败：{}", e.getMessage(), e);
            return Result.error("保存失败：" + e.getMessage());
        }
    }

    @Override
    public Result saveEnrolled(String year) {
        if (StrUtil.isBlank(year)) {
            return Result.error("year 参数不能为空");
        }

        String token = TokenManager();
        if (StrUtil.isBlank(token)) {
            return Result.error("获取 token 失败");
        }

        String endpoint = "/api/v1/student/enrolled";
        String baseUrl = ybtConfig.getUrl();

        int total = 0;

        try {
            // 1. 全市汇总数据
            JSONObject summaryForm = new JSONObject();
            summaryForm.put("year", year);

            JSONObject summaryResult = ApiDbHelper.postAndParse(token, baseUrl, endpoint, summaryForm);
            JSONArray summaryArray = summaryResult.getJSONArray("data");

            if (CollUtil.isNotEmpty(summaryArray)) {
                for (int i = 0; i < summaryArray.size(); i++) {
                    JSONObject item = summaryArray.getJSONObject(i);
                    Enrolled entity = new Enrolled();
                    entity.setCounty("全市汇总");
                    entity.setName(item.getString("name"));
                    entity.setZxs(item.getInteger("zxs"));
                    entity.setZs(item.getInteger("zs"));

                    ApiDbHelper.fillTimestamps(entity);
                    ApiDbHelper.insertOrUpdate(enrolledMapper, entity, wrapper ->
                            wrapper.eq(Enrolled::getCounty, entity.getCounty())
                                    .eq(Enrolled::getName, entity.getName())
                    );
                    total++;
                }
            }

            // 2. 区县数据
            Result countyResult = oneFormService.countyList(year);
            if (countyResult != null && countyResult.getCode() == 0) {
                return Result.error("获取区县列表失败");
            }

            JSONArray countyArray = (JSONArray) countyResult.getData();
            for (int i = 0; i < countyArray.size(); i++) {
                JSONObject county = countyArray.getJSONObject(i);
                String countyName = county.getString("countyName");
                if (StrUtil.isBlank(countyName)) continue;

                JSONObject form = new JSONObject();
                form.put("year", year);
                form.put("name", countyName);

                JSONObject result = ApiDbHelper.postAndParse(token, baseUrl, endpoint, form);
                JSONArray dataArray = result.getJSONArray("data");
                if (CollUtil.isEmpty(dataArray)) continue;

                for (int j = 0; j < dataArray.size(); j++) {
                    JSONObject item = dataArray.getJSONObject(j);
                    Enrolled entity = new Enrolled();
                    entity.setCounty(countyName);
                    entity.setName(item.getString("name"));
                    entity.setZxs(item.getInteger("zxs"));
                    entity.setZs(item.getInteger("zs"));

                    ApiDbHelper.fillTimestamps(entity);
                    ApiDbHelper.insertOrUpdate(enrolledMapper, entity, wrapper ->
                            wrapper.eq(Enrolled::getCounty, entity.getCounty())
                                    .eq(Enrolled::getName, entity.getName())
                    );
                    total++;
                }
            }

            log.info("在校生招生人数数据保存完成，共 {} 条", total);
            return Result.success("在校生招生人数数据保存完成，共 " + total + " 条记录");

        } catch (Exception e) {
            log.error("在校生招生人数数据保存失败：{}", e.getMessage(), e);
            return Result.error("保存失败：" + e.getMessage());
        }
    }

    @Override
    public Result savePhysical(String year) {
        if (StrUtil.isBlank(year)) {
            return Result.error("year 参数不能为空");
        }

        String token = TokenManager();
        if (StrUtil.isBlank(token)) {
            return Result.error("获取 token 失败");
        }

        String endpoint = "/api/v1/student/physical";
        String baseUrl = ybtConfig.getUrl();

        int total = 0;

        try {
            // 1. 全市汇总数据
            JSONObject summaryForm = new JSONObject();
            summaryForm.put("year", year);

            JSONObject summaryResult = ApiDbHelper.postAndParse(token, baseUrl, endpoint, summaryForm);
            JSONArray summaryArray = summaryResult.getJSONArray("data");

            if (CollUtil.isNotEmpty(summaryArray)) {
                for (int i = 0; i < summaryArray.size(); i++) {
                    JSONObject item = summaryArray.getJSONObject(i);
                    Physical entity = new Physical();
                    entity.setCounty("全市汇总");
                    entity.setName(item.getString("name"));
                    entity.setNum(item.getInteger("num"));
                    entity.setPercent(item.getString("percent"));

                    ApiDbHelper.fillTimestamps(entity);
                    ApiDbHelper.insertOrUpdate(physicalMapper, entity, wrapper ->
                            wrapper.eq(Physical::getCounty, entity.getCounty())
                                    .eq(Physical::getName, entity.getName())
                    );
                    total++;
                }
            }

            // 2. 区县数据
            Result countyResult = oneFormService.countyList(year);
            if (countyResult != null && countyResult.getCode() == 0) {
                return Result.error("获取区县列表失败");
            }

            JSONArray countyArray = (JSONArray) countyResult.getData();
            for (int i = 0; i < countyArray.size(); i++) {
                JSONObject county = countyArray.getJSONObject(i);
                String countyName = county.getString("countyName");
                if (StrUtil.isBlank(countyName)) continue;

                JSONObject form = new JSONObject();
                form.put("year", year);
                form.put("name", countyName);

                JSONObject result = ApiDbHelper.postAndParse(token, baseUrl, endpoint, form);
                JSONArray dataArray = result.getJSONArray("data");
                if (CollUtil.isEmpty(dataArray)) continue;

                for (int j = 0; j < dataArray.size(); j++) {
                    JSONObject item = dataArray.getJSONObject(j);
                    Physical entity = new Physical();
                    entity.setCounty(countyName);
                    entity.setName(item.getString("name"));
                    entity.setNum(item.getInteger("num"));
                    entity.setPercent(item.getString("percent"));

                    ApiDbHelper.fillTimestamps(entity);
                    ApiDbHelper.insertOrUpdate(physicalMapper, entity, wrapper ->
                            wrapper.eq(Physical::getCounty, entity.getCounty())
                                    .eq(Physical::getName, entity.getName())
                    );
                    total++;
                }
            }

            log.info("学生体质健康优良率数据保存完成，共 {} 条", total);
            return Result.success("学生体质健康优良率数据保存完成，共 " + total + " 条记录");

        } catch (Exception e) {
            log.error("学生体质健康优良率数据保存失败：{}", e.getMessage(), e);
            return Result.error("保存失败：" + e.getMessage());
        }
    }

    @Override
    public Result saveVariousTypes(String year) {
        if (StrUtil.isBlank(year)) {
            return Result.error("year 参数不能为空");
        }

        String token = TokenManager();
        if (StrUtil.isBlank(token)) {
            return Result.error("获取 token 失败");
        }

        String endpoint = "/api/v1/student/variousTypes";
        String baseUrl = ybtConfig.getUrl();
        int total = 0;

        try {
            // 获取区县列表
            Result countyResult = oneFormService.countyList(year);
            if (countyResult == null || countyResult.getCode() != 200) {
                return Result.error("获取区县列表失败");
            }

            JSONArray countyArray = (JSONArray) countyResult.getData();
            for (int i = 0; i < countyArray.size(); i++) {
                JSONObject county = countyArray.getJSONObject(i);
                String countyName = county.getString("countyName");
                if (StrUtil.isBlank(countyName)) continue;

                JSONObject form = new JSONObject();
                form.put("year", year);
                form.put("name", countyName);

                JSONObject result = ApiDbHelper.postAndParse(token, baseUrl, endpoint, form);
                JSONArray dataArray = result.getJSONArray("data");
                if (CollUtil.isEmpty(dataArray)) continue;

                for (int j = 0; j < dataArray.size(); j++) {
                    JSONObject typeItem = dataArray.getJSONObject(j);
                    String typeName = typeItem.getString("name");
                    JSONArray valueArray = typeItem.getJSONArray("value");

                    for (int k = 0; k < valueArray.size(); k++) {
                        JSONObject item = valueArray.getJSONObject(k);
                        VariousTypes entity = new VariousTypes();
                        entity.setCounty(countyName);
                        entity.setType(typeName);
                        entity.setName(item.getString("name"));
                        entity.setNum(item.getIntValue("num"));
                        entity.setPercent(item.getString("percent"));

                        ApiDbHelper.fillTimestamps(entity);
                        ApiDbHelper.insertOrUpdate(variousTypesMapper, entity, wrapper ->
                                wrapper.eq(VariousTypes::getCounty, entity.getCounty())
                                        .eq(VariousTypes::getType, entity.getType())
                                        .eq(VariousTypes::getName, entity.getName())
                        );
                        total++;
                    }
                }
            }

            log.info("各类型学生情况数据保存成功，共 {} 条", total);
            return Result.success("各类型学生情况数据保存成功，共 " + total + " 条记录");

        } catch (Exception e) {
            log.error("保存各类型学生情况失败：{}", e.getMessage(), e);
            return Result.error("保存失败：" + e.getMessage());
        }
    }

    @Override
    public Result saveAlteration(String year) {
        if (StrUtil.isBlank(year)) {
            return Result.error("year 参数不能为空");
        }

        String token = TokenManager();
        if (StrUtil.isBlank(token)) {
            return Result.error("获取 token 失败");
        }

        String endpoint = "/api/v1/student/alteration";
        String baseUrl = ybtConfig.getUrl();

        int total = 0;

        try {

            Result countyResult = oneFormService.countyList(year);
            if (countyResult == null || countyResult.getCode() != 200) {
                return Result.error("获取区县列表失败");
            }

            JSONArray countyArray = (JSONArray) countyResult.getData();

            for (int i = 0; i < countyArray.size(); i++) {
                JSONObject countyObj = countyArray.getJSONObject(i);
                String countyName = countyObj.getString("countyName");
                if (StrUtil.isBlank(countyName)) continue;

                JSONObject form = new JSONObject();
                form.put("year", year);
                form.put("name", countyName);

                JSONObject response = ApiDbHelper.postAndParse(token, baseUrl, endpoint, form);
                JSONArray dataArray = response.getJSONArray("data");
                if (CollUtil.isEmpty(dataArray)) continue;

                for (int j = 0; j < dataArray.size(); j++) {
                    JSONObject stageObj = dataArray.getJSONObject(j);
                    String stage = stageObj.getString("name");
                    JSONArray valueArray = stageObj.getJSONArray("value");

                    for (int k = 0; k < valueArray.size(); k++) {
                        JSONObject item = valueArray.getJSONObject(k);

                        Alteration entity = new Alteration();
                        entity.setCounty(countyName);
                        entity.setType(stage);
                        entity.setName(item.getString("name"));

                        // 某些数据为 "—"，转为 null 或 0
                        String numStr = item.getString("num");
                        if (StrUtil.isNumeric(numStr)) {
                            entity.setNum(item.getIntValue("num"));
                        } else {
                            entity.setNum(0);
                        }

                        ApiDbHelper.fillTimestamps(entity);
                        ApiDbHelper.insertOrUpdate(alterationMapper, entity, wrapper ->
                                wrapper.eq(Alteration::getCounty, countyName)
                                        .eq(Alteration::getType, stage)
                                        .eq(Alteration::getName, item.getString("name"))
                        );
                        total++;
                    }
                }
            }

            log.info("学生异动数据保存成功，共 {} 条", total);
            return Result.success("学生异动数据保存成功，共 " + total + " 条记录");

        } catch (Exception e) {
            log.error("保存学生异动数据失败：{}", e.getMessage(), e);
            return Result.error("保存失败：" + e.getMessage());
        }
    }

    @Override
    public Result saveCountyStudentNum(String year) {
        if (StrUtil.isBlank(year)) {
            return Result.error("year 参数不能为空");
        }

        String token = TokenManager();
        if (StrUtil.isBlank(token)) {
            return Result.error("获取 token 失败");
        }

        String endpoint = "/api/v1/student/countyStudentNum";
        String baseUrl = ybtConfig.getUrl();
        int total = 0;

        try {
            JSONObject form = new JSONObject();
            form.put("year", year);

            JSONObject response = ApiDbHelper.postAndParse(token, baseUrl, endpoint, form);
            JSONArray dataArray = response.getJSONArray("data");

            if (CollUtil.isEmpty(dataArray)) {
                return Result.error("接口返回数据为空");
            }

            for (int i = 0; i < dataArray.size(); i++) {
                JSONObject countyItem = dataArray.getJSONObject(i);
                String countyName = countyItem.getString("name");
                JSONArray valueArray = countyItem.getJSONArray("value");

                if (StrUtil.isBlank(countyName) || CollUtil.isEmpty(valueArray)) {
                    continue;
                }

                for (int j = 0; j < valueArray.size(); j++) {
                    JSONObject entry = valueArray.getJSONObject(j);
                    CountyStudent entity = new CountyStudent();
                    entity.setCounty(countyName);
                    entity.setName(entry.getString("name"));
                    entity.setZxs(entry.getIntValue("zxs"));
                    entity.setZs(entry.getIntValue("zs"));

                    ApiDbHelper.fillTimestamps(entity);
                    ApiDbHelper.insertOrUpdate(countyStudentMapper, entity, wrapper ->
                            wrapper.eq(CountyStudent::getCounty, entity.getCounty())
                                    .eq(CountyStudent::getName, entity.getName())
                    );

                    total++;
                }
            }

            log.info("各区县义务/学前教育数据保存完成，共 {} 条", total);
            return Result.success("数据保存完成，共 " + total + " 条记录");

        } catch (Exception e) {
            log.error("保存各区县在校生/招生数据失败：{}", e.getMessage(), e);
            return Result.error("保存失败：" + e.getMessage());
        }
    }

    @Override
    public Result saveLayout(String year) {
        if (StrUtil.isBlank(year)) {
            return Result.error("year 参数不能为空");
        }

        String token = TokenManager();
        if (StrUtil.isBlank(token)) {
            return Result.error("获取 token 失败");
        }

        String endpoint = "/api/v1/data/layout";
        String baseUrl = ybtConfig.getUrl();
        int total = 0;

        try {
            // 1. 保存全市汇总数据
            JSONObject summaryForm = new JSONObject();
            summaryForm.put("year", year);
            JSONObject summaryResult = ApiDbHelper.postAndParse(token, baseUrl, endpoint, summaryForm);
            JSONArray summaryArray = summaryResult.getJSONArray("data");

            if (CollUtil.isNotEmpty(summaryArray)) {
                for (int i = 0; i < summaryArray.size(); i++) {
                    JSONObject item = summaryArray.getJSONObject(i);
                    Layout entity = new Layout();
                    entity.setCounty("全市汇总");
                    entity.setName(item.getString("name"));
                    entity.setNum(item.getIntValue("num"));

                    ApiDbHelper.fillTimestamps(entity);
                    ApiDbHelper.insertOrUpdate(layoutMapper, entity, wrapper ->
                            wrapper.eq(Layout::getCounty, entity.getCounty())
                                    .eq(Layout::getName, entity.getName())
                    );
                    total++;
                }
            }

            // 2. 保存区县数据
            Result countyResult = oneFormService.countyList(year);
            if (countyResult == null || countyResult.getCode() != 200) {
                return Result.error("获取区县列表失败");
            }

            JSONArray countyArray = (JSONArray) countyResult.getData();
            for (int i = 0; i < countyArray.size(); i++) {
                JSONObject county = countyArray.getJSONObject(i);
                String countyName = county.getString("countyName");
                if (StrUtil.isBlank(countyName)) continue;

                JSONObject form = new JSONObject();
                form.put("year", year);
                form.put("name", countyName);

                JSONObject result = ApiDbHelper.postAndParse(token, baseUrl, endpoint, form);
                JSONArray dataArray = result.getJSONArray("data");
                if (CollUtil.isEmpty(dataArray)) continue;

                for (int j = 0; j < dataArray.size(); j++) {
                    JSONObject item = dataArray.getJSONObject(j);
                    Layout entity = new Layout();
                    entity.setCounty(countyName);
                    entity.setName(item.getString("name"));
                    entity.setNum(item.getIntValue("num"));

                    ApiDbHelper.fillTimestamps(entity);
                    ApiDbHelper.insertOrUpdate(layoutMapper, entity, wrapper ->
                            wrapper.eq(Layout::getCounty, entity.getCounty())
                                    .eq(Layout::getName, entity.getName())
                    );
                    total++;
                }
            }

            log.info("学校布点数据保存完成，共 {} 条", total);
            return Result.success("学校布点数据保存完成，共 " + total + " 条记录");
        } catch (Exception e) {
            log.error("保存学校布点数据失败：{}", e.getMessage(), e);
            return Result.error("保存失败：" + e.getMessage());
        }
    }

    @Override
    public Result saveAverageArea(String year) {
        if (StrUtil.isBlank(year)) {
            return Result.error("year 参数不能为空");
        }

        String token = TokenManager();
        if (StrUtil.isBlank(token)) {
            return Result.error("获取 token 失败");
        }

        String endpoint = "/api/v1/data/averageArea";
        String baseUrl = ybtConfig.getUrl();
        int total = 0;

        try {
            // 1. 全市汇总数据
            JSONObject form = new JSONObject();
            form.put("year", year);

            JSONObject summaryResult = ApiDbHelper.postAndParse(token, baseUrl, endpoint, form);
            JSONArray summaryArray = summaryResult.getJSONArray("data");

            if (CollUtil.isNotEmpty(summaryArray)) {
                for (int i = 0; i < summaryArray.size(); i++) {
                    JSONObject item = summaryArray.getJSONObject(i);
                    AverageArea entity = new AverageArea();
                    entity.setCounty("全市汇总");
                    entity.setName(item.getString("name"));
                    entity.setNum(item.getBigDecimal("num"));

                    ApiDbHelper.fillTimestamps(entity);
                    ApiDbHelper.insertOrUpdate(averageAreaMapper, entity, wrapper ->
                            wrapper.eq(AverageArea::getCounty, entity.getCounty())
                                    .eq(AverageArea::getName, entity.getName()));
                    total++;
                }
            }

            // 2. 区县数据
            Result countyResult = oneFormService.countyList(year);
            if (countyResult == null || countyResult.getCode() != 200) {
                return Result.error("获取区县列表失败");
            }

            JSONArray countyArray = (JSONArray) countyResult.getData();
            for (int i = 0; i < countyArray.size(); i++) {
                JSONObject county = countyArray.getJSONObject(i);
                String countyName = county.getString("countyName");
                if (StrUtil.isBlank(countyName)) continue;

                JSONObject detailForm = new JSONObject();
                detailForm.put("year", year);
                detailForm.put("name", countyName);

                JSONObject result = ApiDbHelper.postAndParse(token, baseUrl, endpoint, detailForm);
                JSONArray dataArray = result.getJSONArray("data");
                if (CollUtil.isEmpty(dataArray)) continue;

                for (int j = 0; j < dataArray.size(); j++) {
                    JSONObject item = dataArray.getJSONObject(j);
                    AverageArea entity = new AverageArea();
                    entity.setCounty(countyName);
                    entity.setName(item.getString("name"));
                    entity.setNum(item.getBigDecimal("num"));

                    ApiDbHelper.fillTimestamps(entity);
                    ApiDbHelper.insertOrUpdate(averageAreaMapper, entity, wrapper ->
                            wrapper.eq(AverageArea::getCounty, entity.getCounty())
                                    .eq(AverageArea::getName, entity.getName()));
                    total++;
                }
            }

            log.info("生均校舍面积数据保存完成，共 {} 条", total);
            return Result.success("生均校舍面积数据保存完成，共 " + total + " 条记录");
        } catch (Exception e) {
            log.error("生均校舍面积数据保存失败：{}", e.getMessage(), e);
            return Result.error("保存失败：" + e.getMessage());
        }
    }

    @Override
    public Result saveCampusDetail(String year) {
        // 1. 参数校验
        if (StrUtil.isBlank(year)) {
            return Result.error("year 参数不能为空");
        }

        // 2. 获取认证token
        String token = TokenManager();
        if (StrUtil.isBlank(token)) {
            return Result.error("获取token失败");
        }

        List<JSONObject> allSchools = new ArrayList<>();

        // 3. 获取普通学校列表
        Result schoolResult = oneFormService.schoolList(year, "", "", "", 1, 10000);
        if (schoolResult == null || schoolResult.getCode() != 200) {
            return Result.error("获取学校列表失败");
        }
        JSONObject schoolData = (JSONObject) schoolResult.getData();
        if (schoolData == null || !schoolData.containsKey("list")) {
            return Result.error("学校列表数据格式异常");
        }
        JSONArray schoolList = schoolData.getJSONArray("list");
        if (schoolList != null && !schoolList.isEmpty()) {
            allSchools.addAll(schoolList.toJavaList(JSONObject.class));
        }

        // 4. 获取高校列表
        Result highListResult = oneFormService.highList(year);
        if (highListResult == null || highListResult.getCode() != 200) {
            return Result.error("获取高校列表失败");
        }
        Object highData = highListResult.getData();
        if (highData instanceof JSONArray) {
            JSONArray highSchoolList = (JSONArray) highData;
            if (highSchoolList != null && !highSchoolList.isEmpty()) {
                allSchools.addAll(highSchoolList.toJavaList(JSONObject.class));
            }
        }

        if (allSchools.isEmpty()) {
            return Result.error("学校列表为空");
        }

        String baseUrl = ybtConfig.getUrl();
        String endpoint = "/api/v1/student/detail";
        AtomicInteger total = new AtomicInteger(0);

        // 5. 处理每所学校
        for (JSONObject school : allSchools) {
            String orgNo = school.getString("orgnazitionNo");
            String orgName = school.getString("orgnazitionName");

            try {
                // 6. 获取学校详情数据
                JSONObject form = new JSONObject();
                form.put("year", year);
                form.put("orgnazitionNo", orgNo);

                JSONObject result = ApiDbHelper.postAndParse(token, baseUrl, endpoint, form);
                if (result == null || result.getIntValue("code") != 0) {
                    log.warn("接口请求失败，orgnazitionNo={}, message={}", orgNo,
                            result == null ? "null" : result.getString("message"));
                    continue;
                }

                JSONObject data = result.getJSONObject("data");
                if (data == null) {
                    log.warn("接口返回缺失data，orgnazitionNo={}", orgNo);
                    continue;
                }

                // 7. 构建CampusDetail实体
                CampusDetail detail = new CampusDetail();

                // ========== 基础信息 ==========
                detail.setSchoolName(orgName);
                detail.setSchoolRunningType(data.getString("schoolRunningType"));
                detail.setOwnerType(data.getString("ownerType"));
                detail.setWebSite(data.getString("webSite"));
                detail.setWaterSupply(data.getString("waterSupply"));
                detail.setWash(data.getString("wash"));
                detail.setToilet(data.getString("toilet"));
                detail.setInternet(data.getString("internet"));
                detail.setVisionRate(data.getString("visionRate"));
                // 经纬度
                JSONArray latLong = data.getJSONArray("latLong");
                if (latLong != null && latLong.size() == 2) {
                    detail.setLatitude(latLong.getBigDecimal(0));
                    detail.setLongitude(latLong.getBigDecimal(1));
                }

                // ========== 基础设施与设备 ==========
                JSONArray teachingConditions = data.getJSONArray("TeachingConditions");
                if (teachingConditions != null) {
                    for (int i = 0; i < teachingConditions.size(); i++) {
                        JSONObject item = teachingConditions.getJSONObject(i);
                        String name = item.getString("name");
                        BigDecimal num = item.containsKey("num") ? item.getBigDecimal("num") : null;
                        String percent = item.containsKey("percent") ? item.getString("percent") : null;

                        switch (name) {
                            case "占地面积":
                                detail.setLandArea(num);
                                break;
                            case "绿化用地面积":
                                detail.setLandGreen(num);
                                detail.setLandGreenPercent(percent);
                                break;
                            case "运动场地面积":
                                detail.setLandSports(num);
                                detail.setLandSportsPercent(percent);
                                break;
                            case "其他用地面积":
                                detail.setLandOther(num);
                                detail.setLandOtherPercent(percent);
                                break;
                            case "校园足球场":
                                detail.setCampusFootball(num != null ? num.intValue() : null);
                                break;
                            case "数字终端数":
                                detail.setDigitalTerminalTotal(num != null ? num.intValue() : null);
                                break;
                            case "教师终端数":
                                detail.setTeacherTerminal(num != null ? num.intValue() : null);
                                detail.setTeacherTerminalPercent(percent);
                                break;
                            case "学生终端数":
                                detail.setStudentTerminal(num != null ? num.intValue() : null);
                                detail.setStudentTerminalPercent(percent);
                                break;
                            case "网络多媒体教室":
                                detail.setMultimediaClassroom(num != null ? num.intValue() : null);
                                break;
                            case "固定资产总值":
                                detail.setAssetTotal(num);
                                break;
                            case "教学仪器设备资产值":
                                detail.setAssetDevice(num);
                                break;
                        }
                    }

                }

                // 建筑面积
                JSONObject buildArea = data.getJSONObject("buildArea");
                if (buildArea != null) {
                    detail.setBuildAreaTotal(buildArea.getBigDecimal("num"));
                    detail.setBuildAreaDown(buildArea.getBigDecimal("downNum"));
                    detail.setBuildAreaUp(buildArea.getBigDecimal("upNum"));
                    detail.setBuildAreaUpPercent(buildArea.getString("upPercent"));
                    detail.setBuildAreaDownPercent(buildArea.getString("downPercent"));
                }

                // ========== 房屋用途面积 ==========
                JSONArray teaching = data.getJSONArray("teaching");
                if (teaching != null) {
                    for (int i = 0; i < teaching.size(); i++) {
                        JSONObject item = teaching.getJSONObject(i);
                        String name = item.getString("name").trim();
                        BigDecimal num = item.getBigDecimal("num");
                        switch (name) {
                            case "教室":
                                detail.setHouseClassroom(num);
                                break;
                            case "实验实习用房":
                                detail.setHouseLab(num);
                                break;
                            case "专职科研机构办公及研究用房":
                                detail.setHouseResearch(num);
                                break;
                            case "图书馆":
                                detail.setHouseLibrary(num);
                                break;
                            case "室内体育用房":
                                detail.setHouseGym(num);
                                break;
                            case "师生活动用房":
                                detail.setHouseActivity(num);
                                break;
                            case "会堂":
                                detail.setHouseHall(num);
                                break;
                            case "继续教育用房":
                                detail.setHouseContinueEdu(num);
                                break;
                        }
                    }
                }

                // ========== 学生情况 ==========
                JSONArray studentTypeNum = data.getJSONArray("studentTypeNum");
                for (int i = 0; i < studentTypeNum.size(); i++) {
                    JSONObject item = studentTypeNum.getJSONObject(i);
                    String name = item.getString("name");
                    Integer zxs = item.getInteger("zxs");
                    Integer zs = item.getInteger("zs");
                    Integer xws = item.getInteger("xws");

                    switch (name) {
                        case "小学":
                            detail.setZxsPrimary(zxs);
                            detail.setZsPrimary(zs);
                            break;
                        case "初中":
                            detail.setZxsJunior(zxs);
                            detail.setZsJunior(zs);
                            break;
                        case "高中":
                            detail.setZxsSenior(zxs);
                            detail.setZsSenior(zs);
                            break;
                        case "中职":
                            detail.setZxsVocational(zxs);
                            detail.setZsVocational(zs);
                            break;
                        case "高校":
                            detail.setZxsCollege(zxs);
                            detail.setZsCollege(zs);
                            detail.setXwsCollege(xws);
                            break;
                        case "硕士":
                            detail.setZxsMaster(zxs);
                            detail.setZsMaster(zs);
                            detail.setXwsMaster(xws);
                            break;
                        case "博士":
                            detail.setZxsDoctor(zxs);
                            detail.setZsDoctor(zs);
                            detail.setXwsDoctor(xws);
                            break;
                    }
                }

                // ========== 年级分布 ==========
                JSONArray gradeArr = data.getJSONArray("grade");
                if (gradeArr != null) {
                    for (int i = 0; i < gradeArr.size(); i++) {
                        JSONObject gradeObj = gradeArr.getJSONObject(i);
                        JSONArray gradeList = gradeObj.getJSONArray("gradeList");
                        if (gradeList != null) {
                            for (int j = 0; j < gradeList.size(); j++) {
                                JSONObject g = gradeList.getJSONObject(j);
                                String gname = g.getString("name");
                                Integer num = g.getInteger("num");
                                switch (gname) {
                                    case "一年级":
                                        detail.setGrade1Num(num);
                                        break;
                                    case "二年级":
                                        detail.setGrade2Num(num);
                                        break;
                                    case "三年级":
                                        detail.setGrade3Num(num);
                                        break;
                                    case "四年级":
                                        detail.setGrade4Num(num);
                                        break;
                                    case "五年级":
                                        detail.setGrade5Num(num);
                                        break;
                                    case "六年级":
                                        detail.setGrade6Num(num);
                                        break;
                                    case "七年级":
                                        detail.setGrade7Num(num);
                                        break;
                                    case "八年级":
                                        detail.setGrade8Num(num);
                                        break;
                                    case "九年级":
                                        detail.setGrade9Num(num);
                                        break;
                                }
                            }
                        }
                    }
                }

                // ========== 就业 ==========
                JSONArray job = data.getJSONArray("job");
                if (job != null) {
                    for (int i = 0; i < job.size(); i++) {
                        JSONObject j = job.getJSONObject(i);
                        String name = j.getString("name");
                        Integer num = j.getInteger("num");
                        String percent = j.getString("percent");

                        switch (name) {
                            case "就业":
                                detail.setJobEmploymentNum(num);
                                detail.setJobEmploymentPercent(percent);
                                break;
                            case "升学":
                                detail.setJobFurtherStudyNum(num);
                                detail.setJobFurtherStudyPercent(percent);
                                break;
                            case "其他":
                                detail.setJobOtherNum(num);
                                detail.setJobOtherPercent(percent);
                                break;
                        }
                    }
                }

                // ========== 异动数据 ==========
                JSONArray alterationList = data.getJSONArray("alteration");
                if (alterationList != null) {
                    for (int i = 0; i < alterationList.size(); i++) {
                        JSONObject item = alterationList.getJSONObject(i);
                        String schoolType = item.getString("name");
                        String schoolRunningType = item.getString("schoolRunningType");

                        if (schoolRunningType == null || !schoolRunningType.equals(schoolType)) continue;

                        JSONArray valueList = item.getJSONArray("value");
                        for (int j = 0; j < valueList.size(); j++) {
                            JSONObject entry = valueList.getJSONObject(j);
                            String name = entry.getString("name");
                            String numStr = String.valueOf(entry.get("num"));
                            Integer num = ("—".equals(numStr) || "-".equals(numStr)) ? null : Integer.valueOf(numStr);

                            switch (name) {
                                case "招生":
                                    detail.setAlterationEnroll(num);
                                    break;
                                case "复学":
                                    detail.setAlterationResume(num);
                                    break;
                                case "转入":
                                    detail.setAlterationTransferIn(num);
                                    break;
                                case "其他增加":
                                    detail.setAlterationIncrease(num);
                                    break;
                                case "毕业":
                                    detail.setAlterationGraduate(num);
                                    break;
                                case "结业":
                                    detail.setAlterationFinish(num);
                                    break;
                                case "休学":
                                    detail.setAlterationSuspend(num);
                                    break;
                                case "退学":
                                    detail.setAlterationDrop(num);
                                    break;
                                case "死亡":
                                    detail.setAlterationDie(num);
                                    break;
                                case "转出":
                                    detail.setAlterationTransferOut(num);
                                    break;
                                case "其他减少":
                                    detail.setAlterationReduce(num);
                                    break;
                                default:
                                    break;
                            }
                        }
                    }
                }

                // ========== 体质健康 ==========
                JSONArray physical = data.getJSONArray("physical");
                if (physical != null) {
                    for (int i = 0; i < physical.size(); i++) {
                        JSONObject p = physical.getJSONObject(i);
                        String name = p.getString("name");
                        Integer num = p.getInteger("num");
                        String percent = p.getString("percent");
                        switch (name) {
                            case "优秀":
                                detail.setPhysicalGood(num);
                                detail.setPhysicalGoodPercent(percent);
                                break;
                            case "良好":
                                detail.setPhysicalOk(num);
                                detail.setPhysicalOkPercent(percent);
                                break;
                            case "及格":
                                detail.setPhysicalPass(num);
                                detail.setPhysicalPassPercent(percent);
                                break;
                            case "不及格":
                                detail.setPhysicalFail(num);
                                detail.setPhysicalFailPercent(percent);
                                break;
                        }
                    }
                }
                // ========== 少数民族 ==========
                JSONArray minority = data.getJSONArray("minority");
                if (minority != null) {
                    for (int i = 0; i < minority.size(); i++) {
                        JSONObject m = minority.getJSONObject(i);
                        String name = m.getString("name");
                        Integer num = m.getInteger("num");
                        String percent = m.getString("percentage");

                        switch (name) {
                            case "博士研究生":
                                detail.setMinorityDoctorNum(num);
                                detail.setMinorityDoctorPercent(percent);
                                break;
                            case "硕士研究生":
                                detail.setMinorityMasterNum(num);
                                detail.setMinorityMasterPercent(percent);
                                break;
                            case "普通本科生":
                                detail.setMinorityBachelorNum(num);
                                detail.setMinorityBachelorPercent(percent);
                                break;
                            case "普通专科生":
                                detail.setMinorityJuniorCollegeNum(num);
                                detail.setMinorityJuniorCollegePercent(percent);
                                break;
                            case "成人本科生":
                                detail.setMinorityAdultBachelorNum(num);
                                detail.setMinorityAdultBachelorPercent(percent);
                                break;
                            case "成人专科生":
                                detail.setMinorityAdultCollegeNum(num);
                                detail.setMinorityAdultCollegePercent(percent);
                                break;
                            case "网络（开放）本科生":
                                detail.setMinorityOnlineBachelorNum(num);
                                detail.setMinorityOnlineBachelorPercent(percent);
                                break;
                            case "网络（开放）专科生":
                                detail.setMinorityOnlineCollegeNum(num);
                                detail.setMinorityOnlineCollegePercent(percent);
                                break;
                            case "高职专科学生":
                                detail.setMinorityVocationalCollegeNum(num);
                                detail.setMinorityVocationalCollegePercent(percent);
                                break;
                            case "高职本科学生":
                                detail.setMinorityVocationalBachelorNum(num);
                                detail.setMinorityVocationalBachelorPercent(percent);
                                break;
                            case "中职":
                                detail.setMinoritySecondaryVocationalNum(num);
                                detail.setMinoritySecondaryVocationalPercent(percent);
                                break;
                        }
                    }
                }
                // ========== 特殊群体 ==========
                JSONArray specialGroupList = data.getJSONArray("typeList");

                if (specialGroupList != null) {
                    for (int i = 0; i < specialGroupList.size(); i++) {
                        JSONObject item = specialGroupList.getJSONObject(i);
                        String name = item.getString("name");

                        switch (name) {
                            case "少数民族":
                                detail.setMinorityNum(JSON.toJSONString(item));
                                break;
                            case "寄宿生":
                                detail.setBoardingNum(JSON.toJSONString(item));
                                break;
                            case "随迁子女":
                                detail.setMigrantNum(JSON.toJSONString(item));
                                break;
                            case "农村留守儿童":
                                detail.setLeftBehindNum(JSON.toJSONString(item));
                                break;
                            case "复式班":
                                detail.setMultiGradeNum(JSON.toJSONString(item));
                                break;
                        }
                    }
                }
                // ========== 校区 ==========
                JSONArray areas = data.getJSONArray("areaName");
                if (areas != null) {
                    for (int i = 0; i < areas.size(); i++) {
                        String area = areas.getString(i);
                        switch (i) {
                            case 0:
                                detail.setAreaName1(area);
                                break;
                            case 1:
                                detail.setAreaName2(area);
                                break;
                            case 2:
                                detail.setAreaName3(area);
                                break;
                            case 3:
                                detail.setAreaName4(area);
                                break;
                        }
                    }
                }

                // ========== 其他信息 ==========
                detail.setBedNum(data.getInteger("bedNum"));
                detail.setNonOwnership(data.getInteger("nonOwnership"));
                detail.setHistory(data.getString("history"));

                // 8. 设置时间戳
                ApiDbHelper.fillTimestamps(detail);

                // 9. 保存数据
                ApiDbHelper.insertOrUpdate(campusDetailMapper, detail,
                        wrapper -> wrapper.eq(CampusDetail::getSchoolName, detail.getSchoolName()));

                total.incrementAndGet();


            } catch (Exception e) {
                log.error("处理学校详情异常，orgnazitionNo={}，错误：{}", orgNo, e.getMessage(), e);
            }
        }

        String msg = String.format("校区详情数据保存完成，共%d条", total.get());
        log.info(msg);
        return Result.success(msg);
    }

    @Override
    public Result saveSummary(String year) {

            if (StrUtil.isBlank(year)) {
                return Result.error("year 参数不能为空");
            }

            String token = TokenManager();
            if (StrUtil.isBlank(token)) {
                return Result.error("获取 token 失败");
            }

            String endpoint = "/api/v1/data/summary";
            String baseUrl = ybtConfig.getUrl();
            int total = 0;

            try {
                // 获取区县列表
                Result countyResult = oneFormService.countyList(year);
                if (countyResult == null || countyResult.getCode() != 200) {
                    return Result.error("获取区县列表失败");
                }

                JSONArray countyArray = (JSONArray) countyResult.getData();
                for (int i = 0; i < countyArray.size(); i++) {
                    JSONObject county = countyArray.getJSONObject(i);
                    String countyName = county.getString("countyName");
                    if (StrUtil.isBlank(countyName)) continue;

                    // 请求每个区县的指标数据
                    JSONObject detailForm = new JSONObject();
                    detailForm.put("year", year);
                    detailForm.put("type", 2);
                    detailForm.put("name", countyName);

                    JSONObject result = ApiDbHelper.postAndParse(token, baseUrl, endpoint, detailForm);
                    JSONArray dataArray = result.getJSONArray("data");
                    if (CollUtil.isEmpty(dataArray)) continue;

                    for (int j = 0; j < dataArray.size(); j++) {
                        JSONObject item = dataArray.getJSONObject(j);

                        Summary entity = new Summary();
                        entity.setCountyName(countyName);
                        entity.setSchoolNum(item.getInteger("schoolNum"));
                        entity.setTeacherNum(item.getInteger("teacherNum"));
                        entity.setStudentNum(item.getInteger("studentNum"));

                        // 百分比去掉 "%" 存小数
                        entity.setPuHuiPercent(parsePercent(item.getString("puHuiPercent")));
                        entity.setPublicPercent(parsePercent(item.getString("publicPercent")));

                        // 面积类
                        JSONObject areaObj = item.getJSONObject("areaNum");
                        if (areaObj != null) {
                            entity.setCoverArea(areaObj.getBigDecimal("coverArea"));
                            entity.setTeachingArea(areaObj.getBigDecimal("teachingArea"));
                            entity.setSchoolHouseArea(areaObj.getBigDecimal("schoolHouseArea"));
                        }

                        ApiDbHelper.fillTimestamps(entity);
                        ApiDbHelper.insertOrUpdate(summaryMapper, entity, wrapper ->
                                wrapper.eq(Summary::getCountyName, entity.getCountyName())
                        );
                        total++;
                    }
                }

                log.info("区县指标汇总数据保存完成，共 {} 条", total);
                return Result.success("区县指标汇总数据保存完成，共 " + total + " 条记录");
            } catch (Exception e) {
                log.error("区县指标汇总数据保存失败：{}", e.getMessage(), e);
                return Result.error("保存失败：" + e.getMessage());
            }
        }
    /**
     * 百分比解析
     */
    private BigDecimal parsePercent(String percentStr) {
        if (StrUtil.isBlank(percentStr)) return null;
        if (percentStr.endsWith("%")) {
            percentStr = percentStr.replace("%", "");
        }
        return new BigDecimal(percentStr);
    }
}